#!/usr/bin/ruby
# -*- ruby -*-
#
# http://programmingpraxis.com/2013/01/01/happy-new-year/

require 'set'

numbers  = %w{10 9 8 7 6 5 4 3 2 1}
operands = %w{+ - * /} + ['']

def comb(numbers, operands, &accept)
    acc = Set.new

    _comb(numbers, operands, acc, "", &accept)

    return acc
end

def _comb(numbers, operands, acc, curr = "", &accept)
    unless numbers.empty?
        n = numbers.shift

        to_append = numbers.empty? ? n : operands.map { |o| n + o }

        to_append.each do |to_append|
            _comb(numbers.dup, operands, acc, curr + to_append, &accept)
        end
    else
        (acc << curr) if (accept.nil? or accept.call(curr))
    end
end

pp comb(numbers, operands) { |c| eval(c) == 2013 }.to_a.sort
